package com.budwk.app.sqfw.services.common.impl;

import cn.hutool.json.JSONUtil;
import com.budwk.app.common.config.AppException;
import com.budwk.app.sqfw.dto.onlineExcel.SqfwExcelOnlineAllDTO;
import com.budwk.app.sqfw.dto.onlineExcel.SqfwFormSummaryOnlineDTO;
import com.budwk.app.sqfw.models.Sqfw_datamange_community;
import com.budwk.app.sqfw.models.Sqfw_formSummary_new;
import com.budwk.app.sqfw.services.SqfwFormsummaryNewService;
import com.budwk.app.sqfw.services.datamange.DataMangeCommunityService;
import com.budwk.app.sqfw.utils.CommunityDataCleanUtils;
import com.budwk.app.util.ThreadPoolExecutorUtil;
import com.budwk.app.util.poiUtils.nutzBeanUtils.NutzIocUtils;
import com.budwk.starter.common.constant.RedisConstant;
import com.budwk.starter.common.result.ResultCode;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.nutz.aop.interceptor.ioc.TransAop;
import org.nutz.dao.Cnd;
import org.nutz.ioc.aop.Aop;
import org.nutz.ioc.loader.annotation.IocBean;
import org.nutz.lang.random.R;
import org.nutz.plugins.wkcache.annotation.CacheRemove;

import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @program: community-admin
 * @description: 社区数据清洗服务实现
 * @author: LJT
 * @create: 2024-06-08 12:11
 **/
@IocBean(args = {"refer:dao"})
@Slf4j
public class SqfwCommunityDataCleanService {

    private final Object LOCK = new Object();


    @Aop(TransAop.READ_COMMITTED)
    public void cleanDataByType(List<String> ids, String type) {
        if (ObjectUtils.isEmpty(ids) || StringUtils.isEmpty(type)) {
            throw new AppException(ResultCode.PARAM_ERROR.getMsg());
        }
        SqfwFormsummaryNewService sqfwFormsummaryNewService = (SqfwFormsummaryNewService) NutzIocUtils.getBeanByType(SqfwFormsummaryNewService.class);
        List<Sqfw_formSummary_new> sqfwFormSummaryNewList = sqfwFormsummaryNewService.query(Cnd.where("id", "IN", ids));
        // 获取所有相关数据字段
        String configJson = CommunityDataCleanUtils.queryDictFieldInfoByType(type);
        if (StringUtils.isEmpty(configJson)) {
            log.info("===============未查询到对应的数据字典field type===============");
            return;
        }
        LinkedHashMap<String, String> fieldMap = new LinkedHashMap<>();
        CommunityDataCleanUtils.parseDictFeild(configJson, fieldMap);

        List<SqfwFormSummaryOnlineDTO> onlineList = Collections.synchronizedList(new ArrayList<SqfwFormSummaryOnlineDTO>());

        // 检查是 该类型是否有对应的excel头,没有才插入
        DataMangeCommunityService sqfwOnline = (DataMangeCommunityService) NutzIocUtils.getBeanByType(DataMangeCommunityService.class);
        List<Sqfw_datamange_community> sqfwFormSummaryOnline = sqfwOnline.query(
                Cnd.where(Sqfw_datamange_community::getType, "=", type));
        if (sqfwFormSummaryOnline.size() <= 0) {
            SqfwFormSummaryOnlineDTO sqfwFormSummaryOnlineDTO = new SqfwFormSummaryOnlineDTO();
            sqfwFormSummaryOnlineDTO.setExcelDataMap(fieldMap);
            onlineList.add(sqfwFormSummaryOnlineDTO);
        } else {
            // to do 检查是否有新增列，更新旧数据
        }

        // 清洗param_data数据
        CommunityDataCleanUtils.cleanParamData(sqfwFormSummaryNewList, onlineList, fieldMap);

        // 组装excel数据,需要排序，所以插入表操作分开写
        List<Sqfw_datamange_community> sqfwFormSummaryOnlines = Collections.synchronizedList(new ArrayList<Sqfw_datamange_community>());
        buildExcelData(onlineList, sqfwFormSummaryOnlines, type);

        // 插入表
        excelDataBatchInsert(sqfwFormSummaryOnlines);
    }

    @Aop(TransAop.READ_COMMITTED)
    public void cleanDataByAll(List<String> ids) {
        if (ObjectUtils.isEmpty(ids)) {
            throw new AppException(ResultCode.PARAM_ERROR.getMsg());
        }
        SqfwFormsummaryNewService sqfwFormsummaryNewService = (SqfwFormsummaryNewService) NutzIocUtils.getBeanByType(SqfwFormsummaryNewService.class);
        List<Sqfw_formSummary_new> sqfwFormSummaryNewList = sqfwFormsummaryNewService.query(Cnd.where("id", "IN", ids));
        // 获取所有相关数据字段
        LinkedHashMap<String, String> dictFields = CommunityDataCleanUtils.queryDictFieldInfoByAll();
        if (null == dictFields) {
            log.info("===============未查询到对应的数据字典field all===============");
            return;
        }
        List<SqfwFormSummaryOnlineDTO> onlineList = Collections.synchronizedList(new ArrayList<SqfwFormSummaryOnlineDTO>());
        SqfwFormSummaryOnlineDTO sqfwFormSummaryOnlineDTO = new SqfwFormSummaryOnlineDTO();
        sqfwFormSummaryOnlineDTO.setExcelDataMap(dictFields);
        onlineList.add(sqfwFormSummaryOnlineDTO);

        // 清洗param_data数据
        CommunityDataCleanUtils.cleanParamData(sqfwFormSummaryNewList, onlineList, dictFields);

        // 组装excel数据,需要排序，所以插入表操作分开写
        List<Sqfw_datamange_community> sqfwFormSummaryOnlines = Collections.synchronizedList(new ArrayList<Sqfw_datamange_community>());
        buildExcelData(onlineList, sqfwFormSummaryOnlines, null);

        // 组装excel数据并插入数据库
        excelDataBatchInsert(sqfwFormSummaryOnlines);
    }

    @Aop(TransAop.READ_COMMITTED)
    public void deleteData(List<String> ids) {
        SqfwFormsummaryNewService sqfwFormsummaryNewService = (SqfwFormsummaryNewService) NutzIocUtils.getBeanByType(SqfwFormsummaryNewService.class);
        sqfwFormsummaryNewService.clear();
        //sqfwFormsummaryOnlineService.update(Chain.make("del_flag", false), Cnd.where("id", "IN", ids));
    }

    /**
     * 组件excel数据,并插入数据库
     */
    private void buildExcelData(List<SqfwFormSummaryOnlineDTO> onlineList, List<Sqfw_datamange_community> sqfwFormSummaryOnlines, String type) {
        DataMangeCommunityService sqfwOnlineService = (DataMangeCommunityService) NutzIocUtils.getBeanByType(DataMangeCommunityService.class);
        String commonId = R.UU32();
        ThreadPoolExecutor threadPoolExecutor = ThreadPoolExecutorUtil.getInstance();
        CompletableFuture[] cf = onlineList.stream().map(item -> CompletableFuture.runAsync(() ->
                        processExcelData(item, sqfwFormSummaryOnlines, commonId, sqfwOnlineService, type), threadPoolExecutor)
                .thenApplyAsync(r -> r)).toArray(CompletableFuture[]::new);
        CompletableFuture.allOf(cf).join();
        log.info("===========================组装Excel报文完成：{}条===========================", sqfwFormSummaryOnlines.size());
       /* onlineList.forEach(item->{
            processExcelData(item, rowCount, numCount, commonId, sqfwOnlineService);
        });*/
    }

    /**
     * 处理excel数据
     */
    private void processExcelData(SqfwFormSummaryOnlineDTO sqfwFormSummaryOnlineDTO, List<Sqfw_datamange_community> sqfwFormSummaryOnlines,
                                  String commonId, DataMangeCommunityService sqfwOnlineService, String type) {
        //synchronized (LOCK) {
        List<SqfwExcelOnlineAllDTO> sqfwExcelOnlineAllDTOS = Collections.synchronizedList(new ArrayList<SqfwExcelOnlineAllDTO>());
        String updateDate = CommunityDataCleanUtils.formatDate(String.valueOf(sqfwFormSummaryOnlineDTO.getCreateDate()));
        AtomicInteger colCount = new AtomicInteger(0);
        for (ConcurrentSkipListMap.Entry<String, String> entry : sqfwFormSummaryOnlineDTO.getExcelDataMap().entrySet()) {
            // 解析到excelJson
            SqfwExcelOnlineAllDTO sqfwExcelOnlineAllDTO = new SqfwExcelOnlineAllDTO();
            sqfwExcelOnlineAllDTO = CommunityDataCleanUtils.parseSummaryData(entry, updateDate);
            sqfwExcelOnlineAllDTOS.add(sqfwExcelOnlineAllDTO);
            sqfwFormSummaryOnlineDTO.setExcelData(JSONUtil.toJsonStr(sqfwExcelOnlineAllDTOS));
            colCount.getAndIncrement();
        }
        sqfwFormSummaryOnlineDTO.setColNum(String.valueOf(colCount.get()));
        log.info("============id:{}, 总列数：{}============", sqfwFormSummaryOnlineDTO.getSqfwSummaryId(), colCount.getAndIncrement());
        sqfwFormSummaryOnlineDTO.setCommonId(commonId);
        sqfwFormSummaryOnlineDTO.setId(R.UU32());
        sqfwFormSummaryOnlineDTO.setDelFlag(false);
        sqfwFormSummaryOnlineDTO.setSqfwSummaryId(sqfwFormSummaryOnlineDTO.getSqfwSummaryId());
        if (StringUtils.isEmpty(sqfwFormSummaryOnlineDTO.getSqfwSummaryId())) {
            sqfwFormSummaryOnlineDTO.setExcelSeg("header");
        } else {
            sqfwFormSummaryOnlineDTO.setExcelSeg("body");
        }
        if (StringUtils.isNotEmpty(type)) {
            sqfwFormSummaryOnlineDTO.setType(type);
        }
        sqfwFormSummaryOnlines.add(sqfwFormSummaryOnlineDTO);
        //}
    }

    /**
     * 将清洗好的Excel数据插入数据库
     */
    @Aop(TransAop.READ_COMMITTED)
    @CacheRemove(cacheName = RedisConstant.WKCACHE + "shequ.sqfw_form_summary_online")
    private void excelDataBatchInsert(List<Sqfw_datamange_community> onlineList) {
        DataMangeCommunityService sqfwOnlineService = (DataMangeCommunityService) NutzIocUtils.getBeanByType(DataMangeCommunityService.class);
        ThreadPoolExecutor threadPoolExecutor = ThreadPoolExecutorUtil.getInstance();
        CompletableFuture[] cf = onlineList.stream().map(item -> CompletableFuture.runAsync(() ->
                        sqfwOnlineService.insert(item), threadPoolExecutor)
                .thenApplyAsync(r -> r)).toArray(CompletableFuture[]::new);
        CompletableFuture.allOf(cf).join();
    }
}
